home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Design
/
WB Collection.iso
/
workbench werkzeuge
/
bildschirmschoner
/
beyondthedark
/
developer
/
source
/
life
/
life.c
next >
Wrap
C/C++ Source or Header
|
1996-04-07
|
19KB
|
821 lines
/* Life Library */
#include <exec/memory.h>
#include <exec/execbase.h>
#include <graphics/gfxbase.h>
#include <intuition/intuitionbase.h>
#include <libraries/iffparse.h>
#include <utility/tagitem.h>
#include <clib/macros.h>
#define __USE_SYSBASE 42
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/utility.h>
#include <math.h>
#include <string.h>
#include <BTD.h>
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *UtilityBase;
/* #define DEBUG YES */
#ifdef DEBUG
void KPrintF(char *,...);
#define DEBUG_PRINTF(a,b) KPrintF(a,b);
#define DEBUG_PRINT(a) KPrintF(a)
#else
#define DEBUG_PRINTF(a,b)
#define DEBUG_PRINT(a)
#endif
#define QTAG(o) (BTD_Client+(o))
#define LP_ChangePat QTAG(0)
#define LP_Shooter QTAG(1)
#define LP_Cycle QTAG(2)
#define LP_Colors QTAG(3)
#define LP_NRow QTAG(4)
#define MAX_CHPT 5000L /* seconds until a new graphic is plotted */
#define MAX_LINES 100L
#define MAX_SHOOT 59L
#define MAX_COLORS 255L
#define MAX_NROW 64L
#define DEF_CHPT 1000L
#define DEF_LINES 10L
#define DEF_SHOOT 10L
#define DEF_COLORS 31L
#define DEF_NROW 32L
#define MAXROWS 155
#define MAXCOLS 144
#define TIMEOUT 30
#define WHITEPEN (LP->BTDDrawInfo->BDI_Pens[0])
struct lifestruct {
struct BTDDrawInfo *BTDDrawInfo;
LONG xs;
LONG ys;
LONG xb;
LONG yb;
LONG sub;
LONG generation;
LONG shooterTime;
LONG shooterTimeOut;
LONG nrows;
LONG ncols;
LONG changepat;
UWORD buffer[(MAXROWS + 2) * (MAXCOLS + 2) + 2];
UWORD tempbuf[MAXCOLS * 2];
UWORD lastbuf[MAXCOLS];
UWORD agebuf[(MAXROWS + 2) * (MAXCOLS + 2)];
LONG ls_RandN,ls_RandF,ls_RandI;
UWORD fates[256];
UWORD colors;
};
#define FindTagData(l,t,d) GetTagData((t),(d),(l))
struct BTDInteger LifeIntParams[] =
{
LP_ChangePat,"Change Pattern",BTDPT_INTEGER,DEF_CHPT,1L,MAX_CHPT,TRUE,
LP_Shooter,"Shooter Time",BTDPT_INTEGER,DEF_SHOOT,1L,MAX_SHOOT,TRUE,
LP_Colors,"Colors",BTDPT_INTEGER,DEF_COLORS,2L,MAX_COLORS,TRUE,
LP_NRow,"Rows & Cols",BTDPT_INTEGER,DEF_NROW,16L,MAX_NROW,TRUE
};
struct BTDNode *LifeParams[] =
{
&LifeIntParams[0].BI_Node,
&LifeIntParams[1].BI_Node,
&LifeIntParams[2].BI_Node,
&LifeIntParams[3].BI_Node,NULL
};
struct BTDInfo LifeInfo =
{
BTDI_Revision,MAKE_ID('L','I','F','E'),
"Life Blanker","Good old James Conway automaton","Markus Illenseer 1994",
LifeParams
};
/* library stuff */
char MyBlankerName[] = "life.btd";
char MyBlankerID[] = "Life Blanker V" VERSION "." REVISION " for BTD";
LONG MyBlankerLibInit(void)
{
if (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L))
{
if (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L))
{
if (UtilityBase=OpenLibrary("utility.library",37L)) return TRUE;
CloseLibrary (&IntuitionBase->LibNode);
}
CloseLibrary (&GfxBase->LibNode);
}
return FALSE;
}
void MyBlankerLibFree(void)
{
CloseLibrary (UtilityBase);
CloseLibrary (&IntuitionBase->LibNode);
CloseLibrary (&GfxBase->LibNode);
}
#define RAND(a,m) (Random(a,m)-(m)/2)
void __regargs InitRandom(struct lifestruct *LP,ULONG Instance)
{
ULONG Time[2];
CurrentTime (&Time[0],&Time[1]);
LP->ls_RandN=(LONG)Time[0];
if (Time[1]<1024L) Time[1]|=1;
else Time[1]>>=10;
Time[1]^=Instance;
LP->ls_RandF=4*Time[1]+1;
LP->ls_RandI=2*Time[1]+1;
}
WORD __regargs Random(struct lifestruct *LP,WORD Max)
{
LP->ls_RandN=LP->ls_RandF*LP->ls_RandN+LP->ls_RandI;
if (LP->ls_RandN<0L) LP->ls_RandN=-LP->ls_RandN;
return (WORD)(LP->ls_RandN%Max);
}
struct BTDInfo *QueryMyBlanker(void)
{
return &LifeInfo;
}
/* Buffer stores the data for each cell. Each cell is stored as
* 8 bits representing the presence of a critter in each of it's
* surrounding 8 cells. There is an empty row and column around
* the whole array to allow stores without bounds checking as well
* as an extra row at the end for the fetches into tempbuf.
*
* Tempbuf stores the data for the next two rows so that we know
* the state of those critter before he was modified by the fate
* of the critters that have already been processed.
*
* Agebuf stores the age of each critter.
*/
#define UPLT 0x01
#define UP 0x02
#define UPRT 0x04
#define LT 0x08
#define RT 0x10
#define DNLT 0x20
#define DN 0x40
#define DNRT 0x80
/* Fates is a lookup table for the fate of a critter. The 256
* entries represent the 256 possible combinations of the 8
* neighbor cells. Each entry is one of BIRTH (create a cell
* or leave one alive), SAME (leave the cell alive or dead),
* or DEATH (kill anything in the cell).
*/
#define BIRTH 0
#define SAME 1
#define DEATH 2
static LONG patterns[][128] = {
{ /* EIGHT */
-3, -3, -2, -3, -1, -3,
-3, -2, -2, -2, -1, -2,
-3, -1, -2, -1, -1, -1,
0, 0, 1, 0, 2, 0,
0, 1, 1, 1, 2, 1,
0, 2, 1, 2, 2, 2,
99
},
{ /* PULSAR */
1, 1, 2, 1, 3, 1, 4, 1, 5, 1,
1, 2, 5, 2,
99
},
{ /* BARBER */
-7, -7, -6, -7,
-7, -6, -5, -6,
-5, -4, -3, -4,
-3, -2, -1, -2,
-1, 0, 1, 0,
1, 2, 3, 2,
3, 4, 5, 4,
4, 5, 5, 5,
99
},
{ /* HERTZ */
-2, -6, -1, -6,
-2, -5, -1, -5,
-7, -3, -6, -3, -2, -3, -1, -3, 0, -3, 1, -3, 5, -3, 6, -3,
-7, -2, -5, -2, -3, -2, 2, -2, 4, -2, 6, -2,
-5, -1, -3, -1, -2, -1, 2, -1, 4, -1,
-7, 0, -5, 0, -3, 0, 2, 0, 4, 0, 6, 0,
-7, 1, -6, 1, -2, 1, -1, 1, 0, 1, 1, 1, 5, 1, 6, 1,
-2, 3, -1, 3,
-2, 4, -1, 4,
99
},
{ /* TUMBLER */
-6, -6, -5, -6, 6, -6, 7, -6,
-6, -5, -5, -5, 6, -5, 7, -5,
-5, 5, 6, 5,
-7, 6, -5, 6, 6, 6, 8, 6,
-7, 7, -5, 7, 6, 7, 8, 7,
-7, 8, -6, 8, 7, 8, 8, 8,
99
},
{ /* PERIOD4 */
-5, -8, -4, -8,
-7, -7, -5, -7,
-8, -6, -2, -6,
-7, -5, -3, -5, -2, -5,
-5, -3, -3, -3,
-4, -2,
99
},
{ /* PERIOD5 */
-5, -8, -4, -8,
-6, -7, -3, -7,
-7, -6, -2, -6,
-8, -5, -1, -5,
-8, -4, -1, -4,
-7, -3, -2, -3,
-6, -2, -3, -2,
-5, -1, -4, -1,
99
},
{ /* PERIOD6 */
-4, -8, -3, -8,
-8, -7, -7, -7, -5, -7,
-8, -6, -7, -6, -4, -6, -1, -6,
-3, -5, -1, -5,
-2, -4,
-3, -2, -2, -2,
-3, -1, -2, -1,
99
},
{ /* PINWHEEL */
-4, -8, -3, -8,
-4, -7, -3, -7,
-4, -5, -3, -5, -2, -5, -1, -5,
-5, -4, -3, -4, 0, -4, 2, -4, 3, -4,
-5, -3, -1, -3, 0, -3, 2, -3, 3, -3,
-8, -2, -7, -2, -5, -2, -2, -2, 0, -2,
-8, -1, -7, -1, -5, -1, 0, -1,
-4, 0, -3, 0, -2, 0, -1, 0,
-2, 2, -1, 2,
-2, 3, -1, 3,
99
},
{ /* ] */
-1, -1, 0, -1, 1, -1,
0, 0, 1, 0,
-1, 1, 0, 1, 1, 1,
99
},
{ /* cc: */
-3, -1, -2, -1, -1, -1, 1, -1, 2, -1, 3, -1,
-3, 0, -2, 0, 1, 0, 2, 0,
-3, 1, -2, 1, -1, 1, 1, 1, 2, 1, 3, 1,
99
},
{ /* DOLBY */
-3, -1, -2, -1, -1, -1, 1, -1, 2, -1, 3, -1,
-3, 0, -2, 0, 2, 0, 3, 0,
-3, 1, -2, 1, -1, 1, 1, 1, 2, 1, 3, 1,
99
},
{ /* HORIZON */
-15, 0, -14, 0, -13, 0, -12, 0, -11, 0,
-10, 0, -9, 0, -8, 0, -7, 0, -6, 0,
-5, 0, -4, 0, -3, 0, -2, 0, -1, 0,
4, 0, 3, 0, 2, 0, 1, 0, 0, 0,
9, 0, 8, 0, 7, 0, 6, 0, 5, 0,
14, 0, 13, 0, 12, 0, 11, 0, 10, 0,
99
},
{ /* SHEAR */
-7, -2, -6, -2, -5, -2, -4, -2, -3, -2,
-2, -2, -1, -2, 0, -2, 1, -2, 2, -2,
-5, -1, -4, -1, -3, -1, -2, -1, -1, -1,
0, -1, 1, -1, 2, -1, 3, -1, 4, -1,
-3, 0, -2, 0, -1, 0, 0, 0, 1, 0,
2, 0, 3, 0, 4, 0, 5, 0, 6, 0,
-10, 1, -9, 1, -8, 1, -7, 1, -6, 1,
-5, 1, -4, 1, -3, 1, -2, 1, -1, 1,
-10, 2, -9, 2, -8, 2, -7, 2, -6, 2,
-5, 2, -4, 2, -3, 2, -2, 2, -1, 2,
99
},
{ /* VERTIGO */
0, -7,
0, -6,
0, -5,
0, -4,
0, -3,
0, -2,
0, -1,
0, 0,
0, 7,
0, 6,
0, 5,
0, 4,
0, 3,
0, 2,
0, 1,
99
},
{ /* CROSSBAR */
-5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 4, 0, 3, 0, 2, 0, 1, 0, 0, 0,
99
},
{ /* GOALPOSTS */
-8, -7, 8, -7,
-8, -6, 8, -6,
-8, -5, 8, -5,
-8, -4, 8, -4,
-8, -3, 8, -3,
-8, -2, 8, -2,
-8, -1, 8, -1,
-8, 0, 8, 0,
-8, 1, 8, 1,
-8, 2, 8, 2,
-8, 3, 8, 3,
-8, 4, 8, 4,
-8, 5, 8, 5,
-8, 6, 8, 6,
-8, 7, 8, 7,
99
},
{ /* \ */
-8, -8, -7, -8,
-7, -7, -6, -7,
-6, -6, -5, -6,
-5, -5, -4, -5,
-4, -4, -3, -4,
-3, -3, -2, -3,
-2, -2, -1, -2,
-1, -1, 0, -1,
0, 0, 1, 0,
1, 1, 2, 1,
2, 2, 3, 2,
3, 3, 4, 3,
4, 4, 5, 4,
5, 5, 6, 5,
6, 6, 7, 6,
7, 7, 8, 7,
99
},
{ /* LABYRINTH */
-4, -4, -3, -4, -2, -4, -1, -4, 0, -4, 1, -4, 2, -4, 3, -4, 4, -4,
-4, -3, 0, -3, 4, -3,
-4, -2, -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, 4, -2,
-4, -1, -2, -1, 2, -1, 4, -1,
-4, 0, -2, 0, -1, 0, 0, 0, 1, 0, 2, 0, 4, 0,
-4, 1, -2, 1, 2, 1, 4, 1,
-4, 2, -2, 2, -1, 2, 0, 2, 1, 2, 2, 2, 4, 2,
-4, 3, 0, 3, 4, 3,
-4, 4, -3, 4, -2, 4, -1, 4, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4,
99
},
{/* ill */
-5, -5, -3, -5, -1, -5,
-5, -4, -3, -4, -1, -4,
-3, -3, -1, -3,
-5, -2, -3, -2, -1, -2,
-5, -1, -3, -1, -1, -1,
-5, 0, -3, 0, -1, 0,
99
},
{/* r-pentomino, extracted from the SF-book 'Ox' from Piers Anthony*/
0, -1, 1, -1,
-1, 0, 0, 0,
0, 1,
99
}
};
#define NPATS (sizeof patterns / sizeof patterns[0])
void drawcell(struct lifestruct *LP,LONG row, LONG col)
{
WORD x1,x2,y1,y2;
SetAPen(LP->BTDDrawInfo->BDI_RPort,WHITEPEN);
if (LP->colors > 2) {
UWORD *loc = LP->buffer + ((row + 1) * (LP->ncols + 2)) + col + 1;
UWORD *ageptr = LP->agebuf + (loc - LP->buffer);
UWORD age = *ageptr;
/* if we aren't up to blue yet, then keep aging the cell. */
if (age < (((LP->colors+2)*7)/10))
++age;
SetAPen(LP->BTDDrawInfo->BDI_RPort,LP->BTDDrawInfo->BDI_Pens[age]);
*ageptr = age;
}
x1=(WORD)(LP->xb + LP->xs * col)-LP->sub;
y1=(WORD)(LP->yb + LP->ys * row)-LP->sub;
x2=(WORD)(LP->xs)-LP->sub-1+x1;
y2=(WORD)(LP->ys)-LP->sub-1+y1;
if(x2<x1) x2=x1;
if(y2<y1) y2=y1;
if(x1<0) x1=0;
if(y1<0) y1=0;
RectFill(LP->BTDDrawInfo->BDI_RPort,x1,y1,x2,y2);
}
void erasecell(struct lifestruct *LP,LONG row, LONG col)
{
WORD x1,x2,y1,y2;
x1=(WORD)(LP->xb + LP->xs * col)-LP->sub;
y1=(WORD)(LP->yb + LP->ys * row)-LP->sub;
x2=(WORD)(LP->xs)-LP->sub-1+x1;
y2=(WORD)(LP->ys)-LP->sub-1+y1;
if(x2<x1) x2=x1;
if(y2<y1) y2=y1;
if(x1<0) x1=0;
if(y1<0) y1=0;
SetAPen(LP->BTDDrawInfo->BDI_RPort,BTD_BgPen);
RectFill(LP->BTDDrawInfo->BDI_RPort,x1,y1,x2,y2);
}
void spawn(struct lifestruct *LP,UWORD *loc)
{
UWORD *ulloc, *ucloc, *urloc, *clloc, *crloc, *llloc, *lcloc, *lrloc,
*arloc;
LONG off, row, col, lastrow;
lastrow = (LP->nrows) * (LP->ncols + 2);
off = loc - LP->buffer;
col = off % (LP->ncols + 2);
row = (off - col) / (LP->ncols + 2);
ulloc = loc - LP->ncols - 3;
ucloc = loc - LP->ncols - 2;
urloc = loc - LP->ncols - 1;
clloc = loc - 1;
crloc = loc + 1;
arloc = loc + 1;
llloc = loc + LP->ncols + 1;
lcloc = loc + LP->ncols + 2;
lrloc = loc + LP->ncols + 3;
if (row == 1) {
ulloc += lastrow;
ucloc += lastrow;
urloc += lastrow;
}
if (row == LP->nrows) {
llloc -= lastrow;
lcloc -= lastrow;
lrloc -= lastrow;
}
if (col == 1) {
ulloc += LP->ncols;
clloc += LP->ncols;
llloc += LP->ncols;
}
if (col == LP->ncols) {
urloc -= LP->ncols;
crloc -= LP->ncols;
lrloc -= LP->ncols;
}
*ulloc |= UPLT;
*ucloc |= UP;
*urloc |= UPRT;
*clloc |= LT;
*crloc |= RT;
*arloc |= RT;
*llloc |= DNLT;
*lcloc |= DN;
*lrloc |= DNRT;
*(LP->agebuf + (loc - LP->buffer)) = 0;
}
void kill(struct lifestruct *LP,UWORD *loc)
{
UWORD *ulloc, *ucloc, *urloc, *clloc, *crloc, *llloc, *lcloc,
*lrloc, *arloc;
LONG off, row, col, lastrow;
lastrow = (LP->nrows) * (LP->ncols + 2);
off = loc - LP->buffer;
col = off % (LP->ncols + 2);
row = (off - col) / (LP->ncols + 2);
ulloc = loc - LP->ncols - 3;
ucloc = loc - LP->ncols - 2;
urloc = loc - LP->ncols - 1;
clloc = loc - 1;
crloc = loc + 1;
arloc = loc + 1;
llloc = loc + LP->ncols + 1;
lcloc = loc + LP->ncols + 2;
lrloc = loc + LP->ncols + 3;
if (row == 1) {
ulloc += lastrow;
ucloc += lastrow;
urloc += lastrow;
}
if (row == LP->nrows) {
llloc -= lastrow;
lcloc -= lastrow;
lrloc -= lastrow;
}
if (col == 1) {
ulloc += LP->ncols;
clloc += LP->ncols;
llloc += LP->ncols;
}
if (col == LP->ncols) {
urloc -= LP->ncols;
crloc -= LP->ncols;
lrloc -= LP->ncols;
}
*ulloc &= ~UPLT;
*ucloc &= ~UP;
*urloc &= ~UPRT;
*clloc &= ~LT;
*crloc &= ~RT;
*arloc &= ~RT;
*llloc &= ~DNLT;
*lcloc &= ~DN;
*lrloc &= ~DNRT;
}
void setcell(struct lifestruct *LP,LONG row, LONG col)
{
UWORD *loc;
loc = LP->buffer + ((row + 1) * (LP->ncols + 2)) + col + 1;
spawn(LP,loc);
drawcell(LP,row, col);
}
void init_fates(struct lifestruct *LP)
{
LONG i, bits, neighbors;
for (i = 0; i < 256; i++) {
neighbors = 0;
for (bits = i; bits; bits &= (bits - 1))
neighbors++;
if (neighbors == 3)
LP->fates[i] = BIRTH;
else if (neighbors == 2)
LP->fates[i] = SAME;
else
LP->fates[i] = DEATH;
}
}
void InitNewLife(struct lifestruct *LP)
{
LONG row, col;
LONG *patptr;
ULONG Time[2];
LP->generation = 0;
CurrentTime (&Time[0],&Time[1]);
LP->shooterTimeOut = Time[0];
SetAPen(LP->BTDDrawInfo->BDI_RPort,BTD_BgPen);
RectFill(LP->BTDDrawInfo->BDI_RPort,LP->BTDDrawInfo->BDI_Left,
LP->BTDDrawInfo->BDI_Top,
LP->BTDDrawInfo->BDI_Width+LP->BTDDrawInfo->BDI_Left-1,
LP->BTDDrawInfo->BDI_Height+LP->BTDDrawInfo->BDI_Top-1);
bzero(LP->buffer, sizeof(LP->buffer));
patptr = &patterns[Random(LP,NPATS)][0];
while ((col = *patptr++) != 99) {
row = *patptr++;
col += LP->ncols / 2;
row += LP->nrows / 2;
setcell(LP,row, col);
}
}
struct lifestruct *InitMyBlanker(struct TagItem *TagList)
{
LONG ChangePat,Shoot,Colors;
struct lifestruct *LP;
struct BTDDrawInfo *BTDDrawInfo;
ULONG *Error,Dummy,Index,Instance;
LONG Step;
LONG row, col, NRow;
LONG *patptr;
ULONG Time[2];
if ((BTDDrawInfo=(struct BTDDrawInfo *)
FindTagData(TagList,BTD_DrawInfo,NULL))==NULL) return NULL;
Error=(LONG *)FindTagData(TagList,BTD_Error,(ULONG)&Dummy);
if ((LP=AllocVec(sizeof(struct lifestruct),MEMF_PUBLIC|MEMF_CLEAR))==NULL)
{
*Error=BTDERR_Memory;
return NULL;
}
ChangePat=FindTagData(TagList,LP_ChangePat,DEF_CHPT);
Instance=FindTagData(TagList,BTD_Instance,0L);
Shoot=FindTagData(TagList,LP_Shooter,DEF_SHOOT);
Colors=FindTagData(TagList,LP_Colors,DEF_COLORS);
NRow=FindTagData(TagList,LP_NRow,DEF_NROW);
LP->BTDDrawInfo=BTDDrawInfo;
InitRandom(LP,Instance);
CurrentTime (&Time[0],&Time[1]);
init_fates(LP);
LP->generation = 0;
LP->shooterTime = Shoot;
LP->shooterTimeOut = Time[0];
LP->colors=Colors;
LP->changepat=ChangePat;
LP->ncols = NRow;
LP->nrows = NRow;
LP->xs = (BTDDrawInfo->BDI_Width-1) / LP->ncols;
LP->ys = (BTDDrawInfo->BDI_Height-1) / LP->nrows;
LP->xb = BTDDrawInfo->BDI_Left+1+(BTDDrawInfo->BDI_Width - LP->xs * LP->ncols) / 2;
LP->yb = BTDDrawInfo->BDI_Top+(BTDDrawInfo->BDI_Height - LP->ys * LP->nrows) / 2;
LP->sub= (LP->xs<4?1:2);
bzero(LP->buffer, sizeof(LP->buffer));
patptr = &patterns[Random(LP,NPATS)][0];
while ((col = *patptr++) != 99) {
row = *patptr++;
col += LP->ncols / 2;
row += LP->nrows / 2;
setcell(LP,row, col);
}
Step=(256/LP->colors);
for(Index=0; Index<LP->colors; Index++)
{
static UWORD r,g,b;
if((r=(Step*Index))>255) r=255;
if((g=(128-Step*Index>128?(Step*Index)*(-1):(Step*Index)))>255) g=255;
if((b=(255-Step*Index))>255) b=255;
BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[Index]]=r;
BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[Index]]=g;
BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[Index]]=b;
}
BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[0]]=0;
BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[0]]=0;
BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[0]]=255;
BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[1]]=255;
BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[1]]=0;
BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[1]]=0;
BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[LP->colors-1]]=16;
BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[LP->colors-1]]=0;
BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[LP->colors-1]]=0;
for(Index=0; Index<LP->colors; Index++)
BTDDrawInfo->BDI_Changed[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
LP->BTDDrawInfo=BTDDrawInfo;
return LP;
}
void EndMyBlanker(struct lifestruct *LP)
{
DEBUG_PRINT("Life: FreeMem\n");
FreeVec (LP);
}
void AnimMyBlanker(struct lifestruct *LP)
{
UWORD *loc, *temploc, *lastloc;
LONG row, col;
UWORD fate;
ULONG Time[2];
loc = LP->buffer + LP->ncols + 2 + 1;
temploc = LP->tempbuf;
/* copy the first 2 rows to the tempbuf */
bcopy(loc, temploc, LP->ncols);
bcopy(loc + LP->ncols + 2, temploc + LP->ncols, LP->ncols);
lastloc = LP->lastbuf;
/* copy the last row to another buffer for wraparound */
bcopy(loc + ((LP->nrows - 1) * (LP->ncols + 2)), lastloc, LP->ncols);
for (row = 0; row < LP->nrows; ++row) {
for (col = 0; col < LP->ncols; ++col) {
fate = LP->fates[*temploc];
*temploc = (row == (LP->nrows - 3)) ?
*(lastloc + col) :
*(loc + (LP->ncols + 2) * 2);
switch (fate) {
case BIRTH:
if (!(*(loc + 1) & RT)) {
spawn(LP,loc);
}
/* NO BREAK */
case SAME:
if (*(loc + 1) & RT) {
drawcell(LP,row, col);
}
break;
case DEATH:
if (*(loc + 1) & RT) {
kill(LP,loc);
erasecell(LP,row, col);
}
break;
}
loc++;
temploc++;
}
loc += 2;
if (temploc >= LP->tempbuf + LP->ncols * 2)
temploc = LP->tempbuf;
}
if (++LP->generation > LP->changepat)
InitNewLife(LP);
/*
* generate a randomized shooter aimed roughly toward the center of the
* screen after timeout.
*/
CurrentTime (&Time[0],&Time[1]);
if (LP->shooterTime>0 && Time[0]-LP->shooterTimeOut > LP->shooterTime) {
LONG hsp = Random(LP,(LP->ncols - 5)) + 3;
LONG vsp = Random(LP,(LP->nrows - 5)) + 3;
LONG hoff = 1;
LONG voff = 1;
if (vsp > LP->nrows / 2)
voff = -1;
if (hsp > LP->ncols / 2)
hoff = -1;
setcell(LP,vsp + 0 * voff, hsp + 2 * hoff);
setcell(LP,vsp + 1 * voff, hsp + 2 * hoff);
setcell(LP,vsp + 2 * voff, hsp + 2 * hoff);
setcell(LP,vsp + 2 * voff, hsp + 1 * hoff);
setcell(LP,vsp + 1 * voff, hsp + 0 * hoff);
CurrentTime (&Time[0],&Time[1]);
LP->shooterTimeOut = Time[0];
}
}
ULONG PenCountMyBlanker(struct TagItem *TagList)
{
return FindTagData(TagList,LP_Colors,DEF_COLORS);
}